
/*-------------------------------------------------------------------------*/
/**
  @file		pq_farm.c
  @author	Renaud Wanschoor
  @date	july 2004
  @version	$Revision: 2.4 $
  @brief	memory allocation

  attempt for memory allocation control, this can be usefull for allocation
  of datastructure and it make it easier to deal with malloc and free !!! (a lot lot easier).
  First i thought i would use these functions only for priority queues (that explains the name)
  but i find these functions nice to avoid stupid seg faults so it is used 
  in other parts as well but this must be used for priority queues
  
  usage is 
  MEM_Init(mem);
  MEM_Need(mem,10,int);
  MEM_Allocate(mem);
  int_arr = MEM_Request(mem,10,int);
  MEM_Free(mem)
  
*/
/*--------------------------------------------------------------------------*/
#include "plib.h"

/** 
 * attempt for memory allocation control, this can be usefull for allocation
 * of datastructure and it make it easier to deal with malloc and free !!! (a lot lot easier)
 *
 * usage is 
 * MEM_Init(mem);
 * MEM_Need(mem,10,int);
 * MEM_Allocate(mem);
 * int_arr = MEM_Request(mem,10,int);
 * MEM_Free(mem)
 */

void   MEM_Init(Mem* f){
  f->s     = 0;
  f->max_s = 0;
  f->mem   = NULL;
}
void __MEM_Need(Mem* f, size_t size){
  NOTICE((f->mem != NULL,"__Mem_Need error code 1 : mem already allocated\n"));
  f->s += size;
}

void __MEM_Needxy(Mem* f, int x, int y, size_t size){
  NOTICE((f->mem != NULL,"__Mem_Need error code 1 : mem already allocated\n"));
  
  f->s += (x*y*size + x*sizeof(void*));
}

void MEM_Allocate(Mem* f){
  NOTICE((f->mem != NULL,"__Mem_Need error code 1 : mem already allocated\n"));
  f->mem = U_malloc(f->s,char,"HeapFarmAllocate error code 1\n");
  f->max_s = f->s;
  f->s     = 0;
}
void   MEM_Free(Mem* f){
  f->max_s = 0;
  f->s     = 0;
  if(f->mem != NULL){
    U_free("HeapFarmFree error code 1\n",&(f->mem),LEND);
  }
}
void* __MEM_Request(Mem* f,size_t size){
  int pos   = f->s;
  char* mem = f->mem;

  WARNING((f->mem == NULL,"__Mem_Request error code 1 : mem not allocated\n"),NULL);
  f->s+=size;
  WARNING((f->s>f->max_s,
	   "HeapFarmRequest error code 2 : not enough memory request : %d, available : %d \n",f->s,f->max_s),
	  NULL);
  return (void*)(mem + pos);
}

void* __MEM_Requestxy(Mem* f,int x, int y, size_t size){
  int i;
  int pos   = f->s;
  char* mem = f->mem;
  char** tmp;

  WARNING((f->mem == NULL,"__Mem_Request error code 1 : mem not allocated\n"),NULL);
  f->s += (x*y*size + x*sizeof(void*));

  WARNING((f->s>f->max_s,
	   "HeapFarmRequest error code 2 : not enough memory request : %d, available : %d \n",f->s,f->max_s),
	  NULL);
  
  tmp    = (char**)(mem + pos);
  tmp[0] = (char*)(tmp + x);
  for(i=1;i<x;i++)
    tmp[i] = tmp[i-1] + (y * size);

  return (void*)tmp;

}

